﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;

namespace Order
{
    [DataContract]
    public class OrderService:DbContext
    {
        [DataMember]
        public DbSet<Order> Orders { get; set; }
        Func<Order, bool> term;
        IOrderedQueryable<Order> inquiry;

        public enum InquiryType
        {
            OrderID, CommodityName, CustomerName, Total
        }
        public OrderService():base("order")
        {
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<OrderService>());
            InquiryInit();
        }
        public void InquiryInit()
        {
            inquiry = from order in Orders
                      where term(order)
                      orderby order.Total descending
                      select order;
        }
        //public void SortBy(Comparison<Order> comparison = null)
        //{
        //    if (comparison == null) orders.Sort();
        //    else orders.Sort(comparison);
        //}
        public void AddOrder(Order order)
        {
            try
            {
                InquiryOrders(order);
            }
            catch(KeyNotFoundException)
            {
                Orders.Add(order);
                SaveChanges();
            }
        }
        public void DeleteOrder(Order order)
        {
            foreach (var o in Orders)
            {
                if (o.Equals(order))
                {
                    Orders.Remove(order);
                    SaveChanges();
                    return;
                }
            }
            throw new KeyNotFoundException("Order");
        }
        public void DeleteOrder(string orderID)
        {
            foreach (var o in Orders)
            {
                if (o.OrderID.Equals(orderID))
                {
                    Orders.Remove(o);
                    SaveChanges();
                    return;
                }
            }
            throw new KeyNotFoundException("OrderID");
        }
        public void ModifyOrder(string orderID, Order newOrder)
        {
            foreach (var order in Orders)
            {
                if (order.OrderID.Equals(orderID))
                {
                    Orders.Remove(order);
                    Orders.Add(newOrder);
                    SaveChanges();
                    return;
                }
            }
            throw new KeyNotFoundException("OrderID");
        }
        public List<Order> InquiryOrders(string info, InquiryType type)
        {
            if (type == InquiryType.CommodityName)
            {
                term = (order) =>
                {
                    foreach (var detail in order.OrderDetails)
                    {
                        foreach (var commodity in detail.Commodities)
                        {
                            if (commodity.Name.Equals(info)) return true;
                        }
                    }
                    return false;
                };
            }
            else if(type==InquiryType.OrderID)
            {
                term = (order) => order.OrderID.Equals(info);
            }
            else
            {
                term = (order) => order.Customer.Name.Equals(info);
            }
            var list = inquiry.ToList();
            if (list.Count == 0) throw new KeyNotFoundException();
            return list;
        }
        public List<Order> InquiryOrders(double total)
        {
            term = (order) => order.Total == total;
            var res = inquiry.ToList();
            if (res.Count == 0) throw new KeyNotFoundException();
            return res;
        }
        //public List<Order> InquiryOrders(Customer customer)
        //{
        //    term = (order) => order.Customer.Equals(customer);
        //    return inquiry.ToList();
        //}
        public List<Order> InquiryOrders(Order order)
        {
            term = o => o.Equals(order);
            var res = inquiry.ToList();
            if (res.Count == 0) throw new KeyNotFoundException();
            return res;
        }
        public void Export(Stream stream)
        {
            DataContractSerializer serializer = new DataContractSerializer(GetType());
            serializer.WriteObject(stream, this);
        }
        public static OrderService Import(Stream stream)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(OrderService));
            var service = serializer.ReadObject(stream) as OrderService;
            service.InquiryInit();
            return service;
        }
    }
}
